遇到鐵人賽的第一個假日,本來想說終於不用上班,可以睡晚一點。結果一睜開眼睛,腦袋馬上跳出一句話:「對齁,今天的文章還是得寫。」
看了一下外面的天氣,目前好像也沒什麼颱風要來的跡象。既然沒有風雨大到哪裡都不能去,就更想趕快把文章寫完,下午還能出去晃晃。
鐵人賽最公平的地方,大概就是它不管今天是平日還是假日,時間一到,文章照樣要交。平日是下班後拖著疲憊的身體寫;假日則是坐在電腦前,一邊想著外面天氣好像不錯,一邊告訴自己:「先把今天這篇寫完再出去。」
原本想說,既然是假日,今天就挑個比較輕鬆的內容。
昨天才剛跟著一個漏洞走完發現、通報、保留編號到正式公開的流程。今天只要把公開後的 CVE Record 打開來看看,應該不會太難吧?
結果點開 CVE JSON 後,映入眼簾的是 cveMetadata、containers、affected、problemTypes,一層包著一層。
好,當我沒說。
假日果然沒有比較輕鬆。
第一次打開 CVE JSON,畫面真的不太親切。看沒幾行,就很想默默把分頁關掉,回到網頁版只看漏洞描述和 CVSS 分數,假裝自己什麼都沒看見。
但問題也出在這裡。
只看描述和分數,很容易漏掉真正會影響判斷的資訊:這份資料是誰提供的、哪些版本受影響、Record 後來有沒有更新,以及眼前這個分數到底是誰算的。
不過別擔心,今天不打算帶大家硬背 JSON schema。
我們只要把一筆 CVE Record 拆成幾個比較看得懂的區塊,弄清楚每一區大概在放什麼。下次再看到整包 JSON,至少不會立刻關掉分頁。
目前的 CVE Record 採用 CVE JSON 5.x 格式。
如果把那些大括號、方括號和逗號先遮起來,一筆 Record 大致可以拆成這幾個部分:

cveMetadata:這筆 Record 的基本資料與狀態。containers.cna:負責發布的 CNA 所提供的主要漏洞資料。containers.adp:其他獲授權的角色後續補上的資料,可能沒有,也可能不只一組。最外層通常還會看到 dataType 和 dataVersion。
這兩個欄位比較像包裹外面的規格標籤,主要是告訴系統:「這包資料是什麼格式、該用哪個版本的規則來讀。」它們很重要,但不是在解釋漏洞怎麼發生。
所以第一次閱讀時,不用每一個欄位都從頭慢慢啃。先認得這幾個大區塊,事情就已經簡單不少。
cveMetadata 可以看成這筆 Record 外面的資料標籤。
它不會告訴你漏洞怎麼利用,主要回答的是:
這是哪一筆紀錄?由誰負責?現在是什麼狀態?什麼時候更新過?
常見欄位包括:
cveId:例如 CVE-2026-12345
assignerOrgId:負責這組 ID 的組織識別碼state:這筆 Record 目前的狀態dateReserved:ID 被保留的時間datePublished:Record 首次發布的時間dateUpdated:Record 最近更新的時間這幾個日期看起來很像,但回答的是不同問題。
dateReserved 是編號被保留的時間,不是漏洞公開的時間;datePublished 是 Record 首次發布的時間,也不代表研究者當天才發現漏洞;dateUpdated 則表示這筆資料後來又被修改過。
例如廠商修正受影響版本、調整描述或新增參考連結,dateUpdated 就可能跟著改變。
所以看到一筆兩年前發布的 CVE,也不要直接認定內容兩年都沒動過。先瞄一眼更新時間,有時會發現它昨天才剛改完。
另外也要注意 state。
如果狀態是 REJECTED,代表這組 ID 已經不再用來指稱一筆有效的獨立漏洞。原因可能是重複指派、後來確認不是安全問題,或有其他需要撤回的情況。
遇到這種紀錄,不要再抱著舊描述繼續分析,應該先看它的 rejection reason,確認發生了什麼事。
不然很可能認真研究半天,最後才發現自己查的是一個已經被判出局的號碼。
看完外面的資料標籤,接下來就可以打開 containers.cna。
一筆已發布 Record 的主要漏洞內容,通常都放在這裡。這份資料由負責該漏洞的 CNA 提供,但 CNA 不一定就是產品廠商,也可能是研究機構、協調單位或其他獲授權的組織。
這個 container 裡的欄位很多,不過實際閱讀時,可以先挑幾個比較重要的看。
providerMetadata 通常會提供組織 ID、簡稱和更新時間,用來標示這個 container 的資料來源。
這個欄位平常看起來很不起眼,但當一筆 Record 同時出現 CNA、CVE Program 或其他 ADP 提供的資料時,它就很重要。
因為不同單位可能會提供不同的 CVSS、CWE 或補充資訊。這時候不能把所有內容攪在一起,再說「官方就是這樣寫」。
先看 provider,才知道這句話、這個分數或這項分類究竟是誰提供的。
簡單來說,吃東西之前先看一下外送單,不然等等連這份餐是誰送來的都搞不清楚。
title 是漏洞的短標題,通常會用一行文字帶出產品、元件或弱點類型,例如:
某元件存在路徑穿越漏洞
它很適合讓人快速掃過,但畢竟只是一行標題,不可能把攻擊條件、受影響版本和實際影響全部塞進去。
而且不是每筆 Record 都一定會有 title。
所以標題可以先看,但不能看完標題就宣布結案。這就像新聞只看標題一樣,很快,但翻車的速度通常也很快。
descriptions 是比較接近人類正常閱讀方式的漏洞描述。
理想情況下,讀完描述後應該能回答幾個問題:
例如只寫:
某產品存在驗證不足漏洞。
看完還是會滿頭問號。
誰可以利用?要不要登入?從遠端就能打嗎?成功後可以讀資料、改設定,還是直接接管系統?
如果能進一步寫成「未通過身分驗證的遠端攻擊者,可透過特定介面修改系統設定」,對後續判斷才比較有幫助。
不過,漏洞描述也不是完整的技術報告。PoC、修補 commit、繞過方式或更詳細的操作流程,通常還是得往 advisory 或其他 references 繼續找。
如果是站在防禦者或維運人員的角度,affected 很可能是整筆 Record 最值得先看的地方。
因為大家最想知道的,通常不是這個洞聽起來有多可怕,而是:
我們公司的版本到底有沒有中?
常見欄位包括:
vendor:產品供應商或維護組織product:受影響的產品versions:各版本是否受影響platforms:特定作業系統、硬體或執行平台modules、programFiles、programRoutines:更細的受影響元件defaultStatus:未逐一列出版本的預設狀態其中 versions 可能會看到:
affected
unaffected
unknown
版本也不一定只寫成一個固定數字,有時會是一整段範圍,例如某個版本以上、某個版本以前,或直到某個修補版本為止。
這時還要留意邊界有沒有包含在內,以及 lessThan、lessThanOrEqual 這類表示方式。
一個很危險的讀法,是看到產品名稱相同,就立刻宣布全部中獎。
實際上,產品分支、平台、模組、設定和版本邊界,都可能改變最後結論。名稱一樣不代表版本一樣,更不代表每一台機器都受影響。
不然看到自家有 Apache,就把所有寫著 Apache 的 CVE 全部丟進緊急修補清單,維運人員大概會先想辦法修補提出清單的人。
problemTypes 常用來放 CWE,例如:
CWE-79: Improper Neutralization of Input During Web Page Generation
它是在描述弱點類型或問題根因,不是另一組漏洞編號。
CVE ID 回答的是「哪一個漏洞」,CWE 則比較像是在回答「這是哪一類問題」。
不過,不是每一筆 Record 都能立刻選到非常精確的 CWE。有時資訊還不夠完整,有時不同提供者也可能做出不同分類。
與其為了把欄位填滿,硬挑一個看起來差不多的 CWE,不如先確認漏洞真正的失效機制。
CWE 和根因分類在第 8 到第 10 天還會再慢慢拆,今天先知道去哪裡找就好。
metrics 可以放 CVSS v3.1、CVSS v4.0 或其他評估資料,通常會包含向量、分數和嚴重程度。
這大概是整筆 Record 裡最容易被第一眼看到的欄位。
畢竟 9.8 看起來就是比一整串版本範圍刺激很多。
但這裡要先記住兩件事:
所以看到某個網站顯示 CVSS 9.8,除了被數字嚇到之外,還要一起看它使用哪個 CVSS 版本、向量怎麼寫,以及這個分數是誰提供的。
如果 CNA container 沒有 metrics,也不代表這筆 CVE 是假的,更不代表它沒有風險。可能只是 CNA 沒有在這個 container 裡提供評分。
分數很方便,但不能把大腦整個外包給分數。
references 會列出與漏洞相關的公開網址,可能包含:
有些 reference 還會帶著 vendor-advisory、patch 或 exploit 等 tag,幫助系統判斷這個連結大概是什麼類型。
不過,tag 只是分類提示,不是品質保證。
真正要確認修補版本、發布時間或利用方式,還是得把原始頁面打開來看。只收藏連結但完全不點進去,就像買了參考書卻只欣賞封面,知識通常不會自己跑進腦袋。
Record 裡還可能看到:
credits:致謝發現者、通報者或協調者timeline:發現、通報、確認與公開的時間線supportingMedia:補充文字或媒體資料solutions:修補或緩解方式workarounds:暫時性的替代措施configurations:容易受影響的特定設定exploits:已知利用資訊這些欄位都很有價值,但不是每筆 Record 都會全部出現。
缺少 workarounds,不代表現實中一定沒有暫時緩解方式;沒有 exploits,也不能直接推論從來沒有人利用過。
比較安全的理解是:
這個資料來源目前沒有在這個欄位提供相關資訊。
「資料裡沒寫」和「現實中不存在」,中間還隔著一段不小的距離。
ADP 是 Authorized Data Publisher,也就是獲授權的資料發布者。
它可以在 CNA 已發布的主要內容之外,補上額外分析、標準化資料或其他參考資訊,同時保留各自的資料來源。
其中,CVE Program 自己後來補上的 references,也可能放在採用 ADP 格式的 CVE Program Container 裡。其他 ADP 則可能補充 CVSS、CWE、CPE、KEV 或 SSVC 等資料。
這種設計的好處是,不同來源不必互相覆蓋。
假設 CNA 算出一組 CVSS,另一個 ADP 根據自己掌握的資訊算出另一組,兩份評估可以同時保留。讀者可以知道誰提供了什麼,再依實際用途決定要採用哪一份。
所以一筆 Record 裡同時出現兩組 CVSS,不一定是系統壞掉,也不一定是有人算錯。
先看它們分別在哪個 container,再檢查 providerMetadata,通常就能知道這兩組資料是從哪裡來的。
千萬不要直接抓第一個數字,然後開始跟別人爭「官方明明就是這一分」。
CVE JSON 能放的東西很多,但不代表每一筆 Record 都必須把所有欄位填滿。
可以先記住:
JSON schema 比較像是提供很多不同尺寸的收納格,讓資料有地方可以放。
但有這個格子,不代表每一筆 CVE 都必須把它塞滿;格子是空的,也不代表世界上完全不存在那項資訊。
只是這一包資料目前沒裝進來而已。
如果今天拿到一筆陌生的 CVE,我通常會照這個順序看:
cveId、state 和 dateUpdated,確認是哪一筆、是否有效,以及最近有沒有更新。affected,確認產品和版本範圍。descriptions。這個順序刻意把產品和版本放在分數前面。
因為自家的資產如果根本不在受影響範圍內,就算 CVSS 是 9.8,也不能直接把它當成這台機器的修補結論。
反過來說,一筆 Record 暫時沒有 CVSS,也不代表可以直接略過。
先確認跟自己有沒有關係,再看它到底有多嚴重,通常比看到紅色高分就開始緊張實際得多。
今天就到這裡了,先去買一點乾糧預防一下XDD